local desc_awec = [[ 
  # 打八张
  ______________________

  ## 基本规则

  支持2~8人游玩。请保证开启了卡牌<b>“扑克牌”</b>。

  2人使用一副牌，3到5人使用2副牌，6到8人使用3副牌。游戏开始时将随机选择一张不是大王或小王的牌作为<b>主牌</b>（此牌的位置将置于牌堆的前 <b>游戏人数×8</b> 的位置），

  与<b>主牌</b>花色相同的牌即为<b>主</b>。

  然后从随机一人开始，每名玩家依次摸一张牌直到各自的牌数达到8张，摸到<b>主牌</b>的玩家即为第一个<b>防守方</b>，其上家则为<b>进攻方</b>。

  进攻方须选择不是大王或小王的牌对防守方<b>出牌</b>，然后除防守方以外的其他玩家需按顺序依次<b>跟牌</b>。

  <b>出牌</b>只能出<b>点数均相同</b>的牌，且至少出一张；
  
  <b>跟牌</b>则可以跟与<b>出牌</b>出的牌<b>点数相同</b>的牌，且可以跟任意张（即也可以不跟）。

  然后防守方须按牌面大小对其他玩家出的和跟的每一张牌进行<b>压牌</b>，需遵循 <b>点数2＜3＜4＜5＜6＜7＜8＜9＜10＜J＜Q＜K＜A＜主牌，花色需相同</b> 的规则，

  其中用<b>主牌</b>压牌无视花色限制，但是若要压的牌也是<b>主牌</b>，则需用点数更大的<b>主牌</b>来<b>压牌</b>。

  每次<b>压牌</b>结束后，其他玩家可在 <b>防守方的牌数足够压完所有跟牌</b> 的情况下继续<b>跟牌</b>，且此时<b>跟牌</b>可跟的点数包括<b>压牌</b>的点数以及之前<b>出牌</b>的点数。

  当无人<b>跟牌</b>或防守方没有牌时，则本轮攻防结束，从进攻方开始每名玩家依次将手牌摸至8张，然后防守方成为进攻方开始<b>攻</b>其的下家，以此循环；

  若防守方没能压下所有牌或选择不<b>压牌</b>，则其需收走所有牌，且其跳过进攻，其下家成为进攻方继续循环。

  ## 其他规则

  当牌堆中没牌时则不再摸牌，此时先打空手牌的玩家成为第一，其后为第二，以此类推。

  压牌时，大王小王可以压任意牌，无视点数花色限制，且一旦使用它们压牌则其他玩家不可再跟牌。

  出牌时，若手牌中仅有大王和小王，则需从弃牌堆中抽取牌作为手牌，小王抽3张，大王抽5张。


]]

-- local test = true
local test = false

local HX = require "packages/huixiangkill/hxfs"

local awec_getLogic = function()
  local awec_logic = GameLogic:subclass("awec_logic")
   --关闭手杀特效
   function awec_logic:prepareForStart()
    local room = self.room
    self:addTriggerSkill(Fk.skills["game_rule"] --[[@as TriggerSkill]])
    for _, trig in ipairs(Fk.global_trigger) do
      if trig:getSkeleton().name ~= "mobile_effect" then
        self:addTriggerSkill(trig)
      end
    end
    for _, trig in ipairs(Fk.legacy_global_trigger) do
      self:addTriggerSkill(trig)
    end
    self.room:sendLog{ type = "$GameStart" }
  end

  function awec_logic:initialize(room)
    GameLogic.initialize(self, room)
    self.room.settings.luckTime = 0
    self.room.timeout = 180
    self.role_table = {
      { "lord" },
      { "lord", "rebel" },
      { "lord", "rebel", "rebel" },
      { "lord", "rebel", "rebel", "rebel" },
      { "lord", "rebel", "rebel", "rebel", "rebel" },
      { "lord", "rebel", "rebel", "rebel", "rebel", "rebel" },
      { "lord", "rebel", "rebel", "rebel", "rebel", "rebel", "rebel" },
      { "lord", "rebel", "rebel", "rebel", "rebel", "rebel", "rebel", "rebel" },
      { "lord", "rebel", "rebel", "rebel", "rebel", "rebel", "rebel", "rebel", "rebel" },
      { "lord", "rebel", "rebel", "rebel", "rebel", "rebel", "rebel", "rebel", "rebel", "rebel" },
    }
  end

  function awec_logic:assignRoles()
    local room = self.room
    local n = #room.players
    local roles = self.role_table[n]
    table.shuffle(roles)

    local players = room.players

    for i = 1, n do
      local p = room.players[i]
      p.role = roles[i]
    end

    for _, p in ipairs(players) do
      room:broadcastProperty(p, "role")
      room:setPlayerProperty(p, "role_shown", true)
    end

    if n <= 2 then
      room:setBanner("hx__AWEC_mode-piles", 1)
      room:sendLog{ type = "游戏人数为 %arg，使用一副牌", arg = "2", toast = true }
    elseif n >= 3 and n <= 5 then
      room:setBanner("hx__AWEC_mode-piles", 2)
      room:sendLog{ type = "游戏人数为 %arg，使用两副牌", arg = "3~5", toast = true }
    elseif n >= 6 and n <= 8 then
      room:setBanner("hx__AWEC_mode-piles", 3)
      room:sendLog{ type = "游戏人数为 %arg，使用三副牌", arg = "6~8", toast = true }
    end
  end

  --- 分配座位
  function awec_logic:adjustSeats()
    local player_circle = {}
    local room = self.room
    room:setBanner("@[:]huixiangmode_rule","awec-intro") --模式简介
    local players = self.room.players
    local p = 1
    for i = 1, #players do
      if players[i].role == "lord" then
        p = i
        break
      end
    end
    for j = p, #players do
      table.insert(player_circle, players[j])
    end
    for j = 1, p - 1 do
      table.insert(player_circle, players[j])
    end
    if table.find(players, function(pid) return pid.id <= 0 end) then
      room:sendLog{ type = "本局存在人机，注意人机将有概率无视压牌规则压牌~", toast = true }
    end
    self.room:arrangeSeats(player_circle)
  end

  function awec_logic:chooseGenerals()
    local room = self.room ---@type Room
    local generalNum = room.settings.generalNum
    local n = room.settings.enableDeputy and 2 or 1
    local players = room.players
    local lord = room:getLord() or players[1]
    room:setCurrent(lord)
    local a1 = #room.general_pile
    local a2 = #room.players * generalNum
    if a1 < a2 then
      room:sendLog{
        type = "#NoEnoughGeneralDraw",
        arg = a1,
        arg2 = a2,
        toast = true,
      }
      room:gameOver("")
    end
    local generals = room:getNGenerals(#players * generalNum)
    local noai = table.filter(players, function(p) return p.id > 0 end)

    local seats = {}
    for _, p in ipairs(noai) do
      table.insert(seats, p.seat)
    end
    table.sort(seats, function(a, b) return a > b end)
    local function getChange(all_cards, can_change, id)
      if not table.contains(noai, room:getPlayerById(id)) then
        return {}
      end
      local seat = room:getPlayerById(id).seat
      local change = {}
      local index = 0
      for i, s in ipairs(seats) do
        if s == seat then
          index = i
          break
        end
      end
      local start_index = (index - 1) * can_change + 1
      local end_index = index * can_change + 1
      change = table.slice(all_cards, start_index, end_index)
      return change
    end

    local can_change = room:getBanner("changeGeneralNum") or generalNum --换将次数
    local all_cards = table.map(HX.getGenerals(can_change * #noai, room.general_pile, generals), Util.NameMapper)
    table.shuffle(all_cards)

    local data_table_true = {}
    for i, p in ipairs(players) do
      local start_index = (i - 1) * generalNum + 1
      local end_index = i * generalNum + 1
      local arg = table.slice(generals, start_index, end_index)
      data_table_true[p.id] = {
        change = getChange(all_cards, can_change, p.id),
        cards = arg,  --generals
        num = n,  --n
        no_c = false, --no_convert
        heg = false, --heg
        type = "askForGeneralsChosen", --rule
        extra = {n = n}, --extra_data
      }
    end
    room:askToMiniGame(players, {
      skill_name = "AskForGeneral",
      game_type = "ChooseGeneralWithCanChange",
      data_table = data_table_true,
      timeout = self.room.settings.generalTimeout,
    })

    for _, p in ipairs(players) do
      local p_result = p.client_reply
      local general = p_result[1]
      local deputy = p_result[2]
      room:prepareGeneral(p, general, deputy)
    end
    room:askToChooseKingdom(players)

    for _, p in ipairs(players) do
      room:broadcastProperty(p, "general")
      room:broadcastProperty(p, "deputyGeneral")
    end

    if test then
      for _, p in ipairs(players) do
        if p.id <= 0 then
          noai[1]:control(p)
        end
      end
    end
  end
  if not test then
    function awec_logic:attachSkillToPlayers()
    end
  end
  return awec_logic
end

local hx__AWEC_mode = fk.CreateGameMode{
  name = "hx__AWEC_mode",
  minPlayer = 2,
  maxPlayer = 8,
  rule = "#hx__AWEC_rule&",
  logic = awec_getLogic,
  is_counted = function(self, room)
    return #room.players >= 2
  end,
  build_draw_pile = function(self)
    local allCardIds = Fk:getAllCardIds()
    local filterCardIds = {}
    local void = {}
    --卡牌白名单
    local white_cards = {"huixiang__poker"}
    for i = #allCardIds, 1, -1 do
      local id = allCardIds[i]
      local card = Fk:getCardById(id)
      if card then
        if card.is_derived or not table.contains(white_cards, card.package.name) then
          table.removeOne(allCardIds, id)
          table.insert(void, id)
        end
        if table.contains(white_cards, card.package.name) then
          if not card.is_derived then
            table.insert(filterCardIds, id)
          end
        end
      end
    end
    return filterCardIds, void
  end,
  surrender_func = function(self, playedTime)
    local surrenderJudge = { { text = "time limitation: 30 s", passed = playedTime >= 30 },
    { text = "awec: Only two", passed = #table.filter(Fk:currentRoom().alive_players, function(p)
    return not (p.dead and p.rest == 0) end) <= 2 and true } }
    return surrenderJudge
  end,
  winner_getter = function(self, victim)
    local room = victim.room
    local alive = table.filter(Fk:currentRoom().alive_players, function(p)
      return not (p.dead and p.rest == 0)
    end)
    if #alive < 2 then
      return "renegade"
    else
      return ""
    end
  end,
}

Fk:loadTranslationTable{
  ["hx__AWEC_mode"] = "打八张",
  [":hx__AWEC_mode"] = desc_awec,
  ["awec: Only two"] = "仅剩两名玩家存活",
  ["#hx__AWEC_rule&"] = "打八张",
  ["awec-intro"] = "打八张(点击查看)",
  [":awec-intro"] = [[
  <br> ## 基本规则
  <br>支持2~8人游玩。请保证开启了卡牌<b>“扑克牌”</b>。
  <br>2人使用一副牌，3到5人使用2副牌，6到8人使用3副牌。游戏开始时将随机选择一张不是大王或小王的牌作为<b>主牌</b>（此牌的位置将置于牌堆的前 <b>游戏人数×8</b> 的位置），
  <br>与<b>主牌</b>花色相同的牌即为<b>主</b>。
  <br>然后从随机一人开始，每名玩家依次摸一张牌直到各自的牌数达到8张，摸到<b>主牌</b>的玩家即为第一个<b>防守方</b>，其上家则为<b>进攻方</b>。
  <br>进攻方须选择不是大王或小王的牌对防守方<b>出牌</b>，然后除防守方以外的其他玩家需按顺序依次<b>跟牌</b>。
  <br><b>出牌</b>只能出<b>点数均相同</b>的牌，且至少出一张；
  <br><b>跟牌</b>则可以跟与<b>出牌</b>出的牌<b>点数相同</b>的牌，且可以跟任意张（即也可以不跟）。
  <br>然后防守方须按牌面大小对其他玩家出的和跟的每一张牌进行<b>压牌</b>，需遵循 <b>点数2＜3＜4＜5＜6＜7＜8＜9＜10＜J＜Q＜K＜A＜主牌，花色需相同</b> 的规则，
  <br>其中用<b>主牌</b>压牌无视花色限制，但是若要压的牌也是<b>主牌</b>，则需用点数更大的<b>主牌</b>来<b>压牌</b>。
  <br>每次<b>压牌</b>结束后，其他玩家可在 <b>防守方的牌数足够压完所有跟牌</b> 的情况下继续<b>跟牌</b>，且此时<b>跟牌</b>可跟的点数包括<b>压牌</b>的点数以及之前<b>出牌</b>的点数。
  <br>当无人<b>跟牌</b>或防守方没有牌时，则本轮攻防结束，从进攻方开始每名玩家依次将手牌摸至8张，然后防守方成为进攻方开始<b>攻</b>其的下家，以此循环；
  <br>若防守方没能压下所有牌或选择不<b>压牌</b>，则其需收走所有牌，且其跳过进攻，其下家成为进攻方继续循环。
  <br> ## 其他规则
  <br>当牌堆中没牌时则不再摸牌，此时先打空手牌的玩家成为第一，其后为第二，以此类推。
  <br>压牌时，大王小王可以压任意牌，无视点数花色限制，且一旦使用它们压牌则其他玩家不可再跟牌。
  <br>出牌时，若手牌中仅有大王和小王，则需从弃牌堆中抽取牌作为手牌，小王抽3张，大王抽5张。
  ]],
  ["@hx__AWEC_mode-Suit"] = "主花色:",
}


return hx__AWEC_mode
